package com.ncmmall.mall.controller.securitys;

import com.ncmmall.application.securitys.logs.OperationLogApplication;
import com.ncmmall.application.securitys.user.UserApplication;
import com.feijin.commons.exceptions.IllegalRequestException;
import com.feijin.commons.securitys.MD5HashUtils;
import com.feijin.commons.webs.Webs;
import com.ncmmall.domain.security.role.Role;
import com.ncmmall.domain.security.user.QWebUser;
import com.ncmmall.domain.security.user.WebUser;
import com.ncmmall.mall.controller.securitys.shiro.Securitys;
import com.ncmmall.mall.params.PageParams;
import com.ncmmall.querychannel.QueryPage;
import com.ncmmall.querychannel.QueryPageRequest;
import com.ncmmall.querychannel.service.QueryChannelService;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * @author tongchun
 * 系统用户管理
 */
@Controller
@RequestMapping(value = "/securitys/users")
@Slf4j
@RequiredArgsConstructor
public class UserController {

    private final QueryChannelService queryChannelService;
    private final OperationLogApplication logApplication;
    private final UserApplication userApplication;

    /**
     * 分页条件筛选
     */
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    private String list(Model model, PageParams pageParams, WebUser user) {
        QueryPageRequest pageRequest = new QueryPageRequest().setPageNo(pageParams.getPageNo());
        Map<String, Object> params = Maps.newHashMap();
        String hql = builderSQL(params, user);
        QueryPage<WebUser> page = queryChannelService.findPage(hql, pageRequest.setParams(params), WebUser.class);
        model.addAttribute("page", page).addAttribute("params", user);

        return "securitys/user/list";
    }

    /**
     * 条件查询
     */
    private String builderSQL(Map<String, Object> params, WebUser user) {
        String sql = "select u from WebUser u where u.role.name = 'ADMIN' or u.role.name = 'SYSTEM' ";
        if (!Strings.isNullOrEmpty(user.getRealName())) {
            sql += " and u.realName like:realname";
            params.put("realname", "%" + user.getRealName() + "%");
        }
        if (!Strings.isNullOrEmpty(user.getUsername())) {
            sql += " and u.username like:username";
            params.put("username", "%" + user.getUsername() + "%");
        }
        return sql;
    }

    /**
     * 添加用户
     */
    @RequestMapping(value = "/create", method = RequestMethod.GET)
    private String create(Model model) {
        model.addAttribute("user", new WebUser()).addAttribute("roles", queryChannelService.findAll("select r from Role r", Collections.emptyMap(), Role.class)).addAttribute("_method", "POST");
        return "securitys/user/form";
    }

    /**
     * 添加用户
     */
    @RequestMapping(value = "/create", method = RequestMethod.POST)
    @ResponseBody
    private Map<String, Object> create(HttpServletRequest request, @ModelAttribute WebUser user) {
        try {

            userApplication.create(user);
            logApplication.eventOfSystem(Securitys.currentUser(), "添加系统用户" + user.getUsername(), Securitys.getIp(request));

        } catch (Exception ex) {
            return ImmutableMap.of("status", false, "message", "提交异常");
        }

        return ImmutableMap.of("status", true);
    }

    /**
     * 编辑用户信息
     */
    @RequestMapping(value = "/{id}/modify", method = RequestMethod.GET)
    private String modify(Model model, @PathVariable("id") long id) {

        WebUser user = queryChannelService.findOne("select u from WebUser u where u.id = :id", ImmutableMap.of("id", id), WebUser.class);
        List<Role> roles = queryChannelService.findAll("select r  from Role r", Role.class);

        model.addAttribute("user", user).addAttribute("_method", "PUT").addAttribute("roles", roles);

        return "securitys/user/form";
    }

    /**
     * 修改用户信息
     */
    @RequestMapping(value = "/{id}/modify", method = RequestMethod.PUT)
    @ResponseBody
    private Map<String, Object> modify(HttpServletRequest request, @ModelAttribute WebUser user) {
        try {
            userApplication.modify(user);
            logApplication.eventOfSystem(Securitys.currentUser(), "修改系统用户信息" + user.getUsername(), Securitys.getIp(request));
            return ImmutableMap.of("status", true);
        } catch (Exception e) {
            log.error("[编辑用户异常]", e);
            return ImmutableMap.of("status", false, "message", "编辑异常");
        }
    }

    /**
     * 删除用户
     */
    @RequestMapping(value = "/remove", method = RequestMethod.DELETE)
    @ResponseBody
    private Map<String, Object> remove(HttpServletRequest request, @RequestHeader("X-Requested-With") String requestWith, @RequestParam("id") long id) {
        try {

            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalRequestException("request must be Ajax!");
            }

            WebUser user = queryChannelService.findOne("select u from WebUser u where u.id = :id", ImmutableMap.of("id", id), WebUser.class);


            logApplication.eventOfSystem(Securitys.currentUser(), "删除系统用户信息" + user.getUsername(), Securitys.getIp(request));
            userApplication.remove(user);

        } catch (Exception e) {
            log.error("[权限删除异常]", e);
            return ImmutableMap.of("status", false);
        }

        return ImmutableMap.of("status", true);
    }

    /**
     * 重置密码为默认的 123456
     */
    @RequestMapping(value = "/reset", method = RequestMethod.PUT)
    @ResponseBody
    private Map<String, Object> reset(HttpServletRequest request, @RequestHeader("X-Requested-With") String requestWith, @RequestParam("id") long id) {

        try {

            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalRequestException("request must be Ajax!");
            }

            WebUser user = queryChannelService.findOne(QWebUser.webUser.id.eq(id), WebUser.class);
            userApplication.resetDefaultPassword(user);

            logApplication.eventOfSystem(Securitys.currentUser(), "重置系统用户密码" + user.getUsername(), Securitys.getIp(request));

            return ImmutableMap.of("status", true);

        } catch (Exception e) {
            return ImmutableMap.of("status", false);

        }
    }

    /**
     * 锁定用户
     */
    @RequestMapping(value = "/lock", method = RequestMethod.PUT)
    @ResponseBody
    private Map<String, Object> lock(HttpServletRequest request, @RequestHeader("X-Requested-With") String requestWith, @RequestParam("id") long id) {
        try {

            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalRequestException("request must be Ajax!");
            }

            WebUser user = queryChannelService.findOne(QWebUser.webUser.id.eq(id), WebUser.class);

            userApplication.lock(user);

            logApplication.eventOfSystem(Securitys.currentUser(), "锁定系统用户" + user.getUsername(), Securitys.getIp(request));

            return ImmutableMap.of("status", true);

        } catch (Exception e) {
            log.error("[锁定用户异常]", e);
            return ImmutableMap.of("status", false);
        }
    }

    /**
     * 解锁用户
     */
    @RequestMapping(value = "/unlock", method = RequestMethod.PUT)
    @ResponseBody
    private Map<String, Object> unlock(HttpServletRequest request, @RequestHeader("X-Requested-With") String requestWith, @RequestParam("id") long id) {
        try {

            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalRequestException("request must be Ajax!");
            }

            WebUser user = queryChannelService.findOne(QWebUser.webUser.id.eq(id), WebUser.class);

            userApplication.unlock(user);

            logApplication.eventOfSystem(Securitys.currentUser(), "解锁系统用户" + user.getUsername(), Securitys.getIp(request));

            return ImmutableMap.of("status", true);

        } catch (Exception e) {
            log.error("[锁定用户异常]", e);
            return ImmutableMap.of("status", false);
        }
    }

    /**
     * 用户信息
     */
    @RequestMapping(value = "/info", method = RequestMethod.GET)
    private String info(Model model) {
        WebUser user = queryChannelService.findOne("select u from WebUser u where u.id = :id", ImmutableMap.of("id", Securitys.currentUser().getId()), WebUser.class);
        model.addAttribute("user", user).addAttribute("_method", "PUT");

        return "securitys/user/info";
    }

    /**
     * 修改基础信息（昵称、姓名、头像、邮箱、手机号、公司信息）
     */
    @RequestMapping(value = "/info", method = RequestMethod.PUT)
    @ResponseBody
    private Map<String, Object> info(HttpServletRequest request, @RequestHeader("X-Requested-With") String requestWith, WebUser params) {
        try {
            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalRequestException("request must be Ajax!");
            }

            userApplication.modify(params);

            logApplication.eventOfSystem(Securitys.currentUser(), "修改系统用户信息" + params.getUsername(), Securitys.getIp(request));

            return ImmutableMap.of("status", true);
        } catch (Exception e) {
            log.error("[修改用户信息异常]", e);
            return ImmutableMap.of("status", false, "message", "修改用户信息失败");
        }
    }

    /**
     * 修改密码页面
     */
    @RequestMapping(value = "/modifyPassword", method = RequestMethod.GET)
    private String modifyPassword(Model model) {
        WebUser user = queryChannelService.findOne("select u from WebUser u where u.id = :id", ImmutableMap.of("id", Securitys.currentUser().getId()), WebUser.class);
        model.addAttribute("user", user).addAttribute("_method", "PUT");
        return "securitys/user/modifyPassword";
    }


    /**
     * 修改密码
     */
    @RequestMapping(value = "/modifyPassword", method = RequestMethod.PUT)
    @ResponseBody
    private Map<String, Object> modifyPassword(HttpServletRequest request, @RequestHeader("X-Requested-With") String requestWith, @RequestParam("oldPassword") String oldPassword, @RequestParam("newPassword") String newPassword) {
        try {

            if (!Webs.isAjaxRequest(requestWith)) {
                throw new IllegalRequestException("request must be Ajax!");
            }

            WebUser user = queryChannelService.findOne("select u from WebUser u where u.id = :id", ImmutableMap.of("id", Securitys.currentUser().getId()), WebUser.class);
            String passwordAsMd5 = MD5HashUtils.asMD5(MD5HashUtils.MD5(oldPassword), Securitys.currentUser().getUsername());
            if (!user.getPassword().equals(passwordAsMd5)) {
                return ImmutableMap.of("status", false, "message", "原密码错误");
            }

            userApplication.modifyPassword(user, newPassword);

            logApplication.eventOfSystem(Securitys.currentUser(), "修改系统用户密码" + user.getUsername(), Securitys.getIp(request));

            Subject subject = SecurityUtils.getSubject();
            Securitys.unactivateUserSession();
            subject.logout();

            return ImmutableMap.of("status", true);
        } catch (Exception e) {
            log.error("[修改密码异常]", e);
            return ImmutableMap.of("status", false, "message", "修改密码失败");
        }
    }


}
